package typejump.units;

import typejump.Settings;

public abstract class Unit {
	/** The base unit of this unit, eg, for Centimeter this would be Meter
	 * (If Meter is the standard length, then the base of Foot would also be Meter) */
	public abstract Unit getBase();
	/** Converts the number in this unit to a number relative to the base unit 
	 * (eg, cm to meters)*/
	public abstract double toBase(double unit);
	/** Converts a number in the base to a number relative to this unit
	 * (Eg, meters to cm) */
	public abstract double fromBase(double base);
	/** Returns the name of this unit (eg, "centimeters") */
	public abstract String getName();
	/** Returns the suffix/abbreviation/thing of this unit (eg, "cm") */
	public abstract String getSuffix();
	
	/** Converts a number in this unit to a number in the other unit 
	 * (eg, [x] in [me] = [y] in [other], return y
	 * @param number
	 * @param old
	 * @return
	 */
	public double toUnit(double number, Unit other) {
		return other.fromBase(this.toBase(number));
	}
	
	@Override
	public String toString() {
		return getName();
	}
	
	/**
	 * Returns true if this Unit measures the same
	 * thing as the other Unit (eg, length)
	 * @param other
	 * @return
	 */
	public boolean sameAttr(Unit other) {
		return getBase() == other.getBase();
	}
	
	public static final Unit SCALAR = createUnit(null, "scalar", "", 1);

	public static Unit createUnit(final Unit base, final String name, final String suffix, final double ratio) {
		return new Unit() {
			public Unit getBase() { return base; }
			public String getName()  { return name; }
			public String getSuffix() { return suffix; }
			public double toBase(double num) { return num / ratio; }
			public double fromBase(double num) { return num * ratio; }
		};
	}
	public static Unit createUnit(final Unit base, final String name, final String suffix, final String ratio) {
		return new Unit() {
			public Unit getBase() { return base; }
			public String getName()  { return name; }
			public String getSuffix() { return suffix; }
			public double toBase(double num) { return num / Settings.getDouble(ratio); }
			public double fromBase(double num) { return num * Settings.getDouble(ratio); }
		};
	}
}
